package com.hcss.common.shiro;

import com.alibaba.fastjson.JSON;
import com.hcss.common.constant.CommonConstants;
import com.hcss.common.constant.ConfigConstants;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.web.filter.AccessControlFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @描述: 跳转登录页面时在打开的新窗口中加载登录页面
 * @作者: xuqian
 * @创建日期: 2018-11-29 9:56
 * @公司 浙江鸿程计算机系统有限公司
 */
public class LoginRedirectFilter extends AccessControlFilter {
    private final ShiroProperties shiroProperties;
    private final ConfigConstants configConstants;

    public LoginRedirectFilter(ShiroProperties shiroProperties, ConfigConstants configConstants) {
        this.shiroProperties = shiroProperties;
        this.configConstants = configConstants;
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        Object object = SecurityUtils.getSubject().getPrincipal();
        if (object != null) {// 已登录，正常执行下面的filter
            return true;
        }
        String servletPath = ((HttpServletRequest)request).getServletPath();
        if (shiroProperties.getLoginUrl().equalsIgnoreCase(servletPath)) {
            return true;
        }

        if (StringUtils.isNotBlank(((HttpServletRequest) request).getHeader(ConfigConstants.MOBILE_HEADER))) {
            // 手机端请求，返回JSON数据
            returnJSON(response);
        } else {
            // PC端请求
            returnPage(request, response);
        }

        return false;
    }

    private void returnPage(ServletRequest request, ServletResponse response) throws Exception {
        if (CommonConstants.XMLHttpRequest.equals(((HttpServletRequest)request).getHeader(CommonConstants.XML_HTTP_REQUEST_KEY))) {
            // 如果是ajax请求响应头会有，x-requested-with，然后设置session状态为timeout
            ((HttpServletResponse)response).setHeader("sessionstatus", "timeout");
            return;
        } else {
            // 页面跳转请求则作为父窗口打开
            String url = getLoginUrl((HttpServletRequest) request);
            PrintWriter out = response.getWriter();
            out.println("<html>");
            out.println("<script>");
            out.println("window.open ('" + url + "','_parent')");
            out.println("</script>");
            out.println("</html>");
        }
    }

    private void returnJSON(ServletResponse response) throws Exception {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = response.getWriter();
        Map<String,Object> map = new HashMap<>();
        map.put("code", "unlogin");
        map.put("message", "用户未登录");
        out.write(JSON.toJSONString(map));
    }

    private String getLoginUrl(HttpServletRequest request) {
        return request.getScheme() + CommonConstants.COLON + CommonConstants.SLASH + CommonConstants.SLASH +
                request.getServerName() + CommonConstants.COLON + request.getServerPort() + request.getContextPath() +
                shiroProperties.getLoginUrl();
    }

}
